package com.css.fxfzypg.modules.maps.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.css.fxfzypg.base.response.RestResponse;
import com.css.fxfzypg.common.utils.AreaBoundaryUtil;
import com.css.fxfzypg.modules.baseData.queryParams.ElevationQueryParams;
import com.css.fxfzypg.modules.hypergraph.service.HypergraphService;
import com.css.fxfzypg.modules.maps.entity.ElevationUnion;
import com.css.fxfzypg.modules.maps.service.ElevationMapService;
import com.css.fxfzypg.modules.qhmapfiles.repository.QhMapFilesImport;
import com.css.fxfzypg.modules.qhmapfiles.repository.QhMapFilesNativeRepository;
import com.css.fxfzypg.modules.qhmapfiles.repository.entity.QhMapFilesEntity;
import com.css.fxfzypg.modules.qhmapfiles.viewobjects.QhMapFilesQueryParams;
import com.css.fxfzypg.util.PlatformDateUtils;
import com.css.fxfzypg.util.PlatformObjectUtils;
import com.css.fxfzypg.util.UUIDGenerator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.gdal.gdal.Band;
import org.gdal.gdal.Dataset;
import org.gdal.gdal.gdal;
import org.gdal.gdalconst.gdalconstConstants;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.geometry.jts.JTS;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.geotools.referencing.CRS;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.io.ParseException;
import org.locationtech.jts.io.WKTReader;
import org.opengis.filter.Filter;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Author zyt
 * @Date: 2022/10/04
 */
@Service
@Slf4j
public class ElevationMapServiceImpl implements ElevationMapService {
    @Autowired
    private QhMapFilesImport qhMapFilesImport;//上传文件管理
    @Autowired
    private QhMapFilesNativeRepository qhMapFilesNativeRepository;
    @Resource
    JdbcTemplate jdbcTemplate;
    @Resource
    NamedParameterJdbcTemplate namedParameterJdbcTemplate;
    @Resource
    HypergraphService hypergraphService;

    /**
     * 数据源
     * 10.19.41.111
     */
    @Value("${spring.datasource.url}")
    private String url = "";
    @Value("${spring.datasource.username}")
    private String name = "";
    @Value("${spring.datasource.password}")
    private String pwd = "";

    /**
     * 获取数据库连接
     * SQL语句
     */
    private Connection getConnection() throws Exception {
        //Class.forName("com.mysql.cj.jdbc.Driver");
        Class.forName("org.postgresql.Driver");
        Connection conn = DriverManager.getConnection(url, name, pwd);
        return conn;
    }

    /*数据模糊全查询*/
    @Override
    public Map<String,Object> getAllData(ElevationQueryParams queryParams) {
        StringBuilder sql = new StringBuilder(" select elevation_number,fileuuid,province,city,county,st_astext(geom) as geom from sys_elevation_union");
        StringBuilder orderSql = new StringBuilder(" order by fileuuid");
        orderSql.append(" limit 5");//test
        StringBuilder whereSql = new StringBuilder("  where 1=1");
        //查询条件
        /*if (!PlatformObjectUtils.isEmpty(queryParams.getProvince()) ){
            whereSql.append(" and province like '%" + queryParams.getProvince() + "%'");
        }*/
        if (!PlatformObjectUtils.isEmpty(queryParams.getProvince()) ){
            String province = queryParams.getProvince();
            String provinceSql = " and province like '%" + province + "%'";
            if(province.indexOf(";")!=-1){//多个省用;间隔
                String[] provinceArr = province.split(";");
                provinceSql = "";
                for(int i=0;i<provinceArr.length;i++){
                    if(!PlatformObjectUtils.isEmpty(provinceArr[i])){
                        if(!PlatformObjectUtils.isEmpty(provinceSql)){
                            provinceSql += ",";
                        }
                        provinceSql += "'" + provinceArr[i] + "'";
                    }
                }
                provinceSql = " and province in (" + provinceSql + ")";
            }
            whereSql.append(provinceSql);
        }
        if (!PlatformObjectUtils.isEmpty(queryParams.getCity()) ){
            whereSql.append(" and city like '%" + queryParams.getCity() + "%'");
        }
        if (!PlatformObjectUtils.isEmpty(queryParams.getCounty()) ){
            whereSql.append(" and county like '%" + queryParams.getCounty() + "%'");
        }
        if (!PlatformObjectUtils.isEmpty(queryParams.getFileuuid()) ){
            whereSql.append(" and fileuuid='" + queryParams.getFileuuid() + "'");
        }

        sql.append(whereSql).append(orderSql).toString();

        List<ElevationUnion> resultList = new ArrayList<ElevationUnion>();
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = getConnection();
            ps = conn.prepareStatement(sql.toString());
            rs = ps.executeQuery();
            while (rs.next()) {
                ElevationUnion elevationUnion = new ElevationUnion();
                elevationUnion.setElevationNumber(rs.getInt("elevation_number"));
                elevationUnion.setGeom(rs.getString("geom"));
                elevationUnion.setFileUuid(rs.getString("fileuuid"));//文件UUID
                elevationUnion.setProvince(rs.getString("province"));
                elevationUnion.setCity(rs.getString("city"));
                elevationUnion.setCounty(rs.getString("county"));

                resultList.add(elevationUnion);
            }
        } catch (Exception e2) {
            e2.printStackTrace();
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
            try {
                if (ps != null) {
                    // 关闭连接
                    ps.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }

        Map<String,Object> map=new HashMap();
        //map.put("total",total);
        //map.put("rows",datas);
        map.put("rows",resultList);
        return map;
    }

    /*根据高程和文件uuid查询数据*/
    @Override
    public Map<String,Object> getDataById(String elevationNumber,String fileUuid) {
        StringBuilder sql = new StringBuilder(" select elevation_number,fileuuid,province,city,county,st_astext(geom) as geom from sys_elevation_union");
        StringBuilder orderSql = new StringBuilder(" order by fileuuid");
        //orderSql.append(" limit 2");
        StringBuilder whereSql = new StringBuilder("  where 1=1");
        //查询条件
        if (!PlatformObjectUtils.isEmpty(elevationNumber) ){
            whereSql.append(" and elevation_number=" + elevationNumber);
        }
        if (!PlatformObjectUtils.isEmpty(fileUuid) ){
            whereSql.append(" and fileuuid='" + fileUuid + "'");
        }

        sql.append(whereSql).append(orderSql).toString();

        List<ElevationUnion> resultList = new ArrayList<ElevationUnion>();
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = getConnection();
            ps = conn.prepareStatement(sql.toString());
            rs = ps.executeQuery();
            while (rs.next()) {
                ElevationUnion elevationUnion = new ElevationUnion();
                elevationUnion.setElevationNumber(rs.getInt("elevation_number"));
                elevationUnion.setGeom(rs.getString("geom"));
                elevationUnion.setFileUuid(rs.getString("fileuuid"));//文件UUID
                elevationUnion.setProvince(rs.getString("province"));
                elevationUnion.setCity(rs.getString("city"));
                elevationUnion.setCounty(rs.getString("county"));

                resultList.add(elevationUnion);
            }
        } catch (Exception e2) {
            e2.printStackTrace();
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
            try {
                if (ps != null) {
                    // 关闭连接
                    ps.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }

        Map<String,Object> map=new HashMap();
        //map.put("total",total);
        //map.put("rows",datas);
        map.put("rows",resultList);
        return map;
    }

    /*逻辑删除文件及相关数据*/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteFileData(List<String> ids, String userId) {
        //逻辑删除文件
        deleteFile(ids, userId);
        //物理删除相关数据
        deleteData(ids);
        //物理删除相关数据--union
        deleteUnionData(ids);
    }

    //逻辑删除文件
    @Transactional(rollbackFor = Exception.class)
    public void deleteFile(List<String> ids, String userId) {
        //逻辑删除文件
        String sql = "update qh_map_files set is_delete = '1' , update_time='"+ PlatformDateUtils.getCurrentTimestamp()+"', update_user = '"+userId+"' where uuid in (:ids)";
        Map map = new HashMap();
        map.put("ids", ids);
        namedParameterJdbcTemplate.update(sql, map);
    }

    //逻辑删除相关数据
    @Transactional(rollbackFor = Exception.class)
    /*public void deleteData(List<String> ids) {
        //逻辑删除相关数据
        String sql = "update sys_elevation set elevation_status = '0' where fileuuid in (:ids)";
        Map map = new HashMap();
        map.put("ids", ids);
        namedParameterJdbcTemplate.update(sql, map);
    }*/

    //物理删除相关数据--union
    public void deleteUnionData(List<String> ids) {
        StringBuilder sql = new StringBuilder("delete from sys_elevation_union where fileuuid in (:ids)");
        Map idMap = new HashMap();
        idMap.put("ids", ids);
        namedParameterJdbcTemplate.update(sql.toString(), idMap);
    }

    //物理删除相关数据
    public void deleteData(List<String> ids) {
        StringBuilder sql = new StringBuilder("delete from sys_elevation where fileuuid in (:ids)");
        Map idMap = new HashMap();
        idMap.put("ids", ids);
        namedParameterJdbcTemplate.update(sql.toString(), idMap);
    }

    //校验tif文件
    public String checkTifFiles(String filePath, String province, String city, String area, String formatDate, String userID) {
        try {
            String returnMsg = "";
            System.out.println(new Date()+"-------------------1.开始readTifFile");
            System.out.println(new Date()+"-------------------2.开始校验");
            //校验Tif文件是否为2000坐标系
            if (!(checkCGCS2000Tif(filePath))){
                System.out.println(new Date()+"-----------校验失败.请上传基于CGCS2000坐标系的.tif数据文件.");
                return "checkNotCGCS2000";
            }
            //获取省市县所在区域字符串
            String boundariesCoordinate = null;
            //读取tif文件并校验--type上传类型（地形地貌（高程）_）
            String codeType = "";
            int dataLength = -1;//数据长度
            String checkResult = null;//校验结果
            //获取tif文件全部数据长度--zyt
            int count = getDataLengthByTIF(filePath);
            if(count>0){
                dataLength = count;
                checkResult = "校验成功";
            }else{
                checkResult = "tif文件中存在不符合字段要求的数据";
            }
            System.out.println(new Date()+"-------------------3.结束readTifFile");
            System.out.println(new Date()+"-----------3.结束校验");
            if(checkResult.equals("校验成功")){
                System.out.println(new Date()+"-----------校验成功.");
                String fileName = filePath.substring(filePath.lastIndexOf("/") + 1, filePath.length() - 4);
                //上传文件信息
                QhMapFilesEntity qhMapFilesEntity = new QhMapFilesEntity();
                qhMapFilesEntity.setUuid(UUIDGenerator.getUUID());
                qhMapFilesEntity.setFilepath(filePath);
                qhMapFilesEntity.setProvince(province);
                qhMapFilesEntity.setCity(city);
                qhMapFilesEntity.setArea(area);
                qhMapFilesEntity.setAffiliatedFileName(fileName);
                qhMapFilesEntity.setDateStr(formatDate);
                qhMapFilesEntity.setIsSave("0");
                qhMapFilesEntity.setIsDelete("0");
                qhMapFilesEntity.setType("地形地貌（高程）_");//类型
                qhMapFilesEntity.setPostfix("tif");
                qhMapFilesEntity.setQualityStatus("1");//上传省市级类型（0：省，1：市）
                qhMapFilesEntity.setCodeType(codeType);//编码类型（0：UTF-8，1：GBK）
                qhMapFilesEntity.setDataLength(dataLength);//数据长度
                qhMapFilesEntity.setCreateUser(userID);//登录人
                System.out.println(new Date()+"-------------------4.开始保存");
                //保存到上传文件管理表
                saveMapFiles(qhMapFilesEntity);
                //根据类型保存到数据库
                returnMsg = saveQhMapFilesToDatabaseByType(qhMapFilesEntity);
                System.out.println(new Date()+"-------------------5.结束保存");
            }else{
                System.out.println(new Date()+"-----------校验失败."+checkResult);
                returnMsg = "上传文件中第"+(dataLength+1)+"行数据#" + checkResult;
            }
            //返回的消息
            return returnMsg;
        } catch (RuntimeException e) {
            log.error(e.getMessage(), e);
            return "插入或更新数据出现错误: <br/>" + e.getMessage();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return "数据导入失败, 服务器内部出现异常!";
        }
    }

    //根据类型保存到数据库
    public String saveQhMapFilesToDatabaseByType(QhMapFilesEntity qhMapFilesEntity) {
        String fileUuid = qhMapFilesEntity.getUuid();
        String type = qhMapFilesEntity.getType();
        String filePath = qhMapFilesEntity.getFilepath();
        String affiliatedFileName = qhMapFilesEntity.getAffiliatedFileName();
        String province = qhMapFilesEntity.getProvince();
        String city = qhMapFilesEntity.getCity();
        String area = qhMapFilesEntity.getArea();
        //String createUser  = qhMapFilesEntity.getCreateUser();
        String postfix = qhMapFilesEntity.getPostfix();//文件类型：tif
        int dataLength = qhMapFilesEntity.getDataLength();
        String createUser = qhMapFilesEntity.getCreateUser();//创建人
        String dateStr = qhMapFilesEntity.getDateStr();//日期
        System.out.println(new Date()+"------开始导入."+affiliatedFileName+"----数据长度."+dataLength);
        //test
        /*if(dataLength>1000000){
            return "导入失败."+affiliatedFileName+"数据长度过大"+dataLength;
        }*/
        String resMsg = affiliatedFileName;//返回结果
        String result = "";
        try{
            //更新为正在保存状态
            updateSaveNowQhMapFile(qhMapFilesEntity);
            //根据日期和类型查询全部文件
            QhMapFilesQueryParams queryParams = new QhMapFilesQueryParams();
            queryParams.setType(type);//上传类型（地形地貌（高程）_）
            //queryParams.setIsDelete("0");//未删除
            //queryParams.setIsSave("0");//未保存
            //queryParams.setProvince(province);
            //queryParams.setCity(city);
            //queryParams.setArea(area);
            queryParams.setDateStr(dateStr);//日期
            List<QhMapFilesEntity> list = searchQhMapFilesByParams(queryParams);
            //上传日期的所有文件数量
            int fileListCount = 0;
            if(list!=null){
                fileListCount = list.size();
            }
            //保存
            if(postfix.equals("tif")){//保存tif文件
//                result = newImportTifFile(filePath,province,city,area,fileUuid,dataLength,createUser,dateStr,fileListCount);
                //调用超图服务tif文件发布
                Map<String, Object> map = new HashMap<>();
                map.put("type", "demTif");//tif发布高程ypg
                map.put("layerName", affiliatedFileName);//图层名称
                map.put("filePath", filePath);//文件路径
                RestResponse restResponse = hypergraphService.getServerToken(map);
                if(restResponse.getData()!=null){
                    JSONObject json = (JSONObject) JSON.toJSON(restResponse.getData());
                    String result1 = (String)json.get("result");
                    if(result1.equals("获取成功！")){
                        //生成成功
                        result = "成功导入" + dataLength + "条数据.";
                    }
                }
            }
            //已保存成功
            if(result.contains("成功导入")){
                /*if(list!=null && list.size()>0){
                    //批量更新为已删除状态
                    updateLogicDeleteQhMapFiles(list);
                }*/
                //更新为已保存状态
                updateSaveQhMapFile(qhMapFilesEntity);
                resMsg += "导入成功." + result + "当前数据所在文件UUID"+fileUuid;
//                resMsg += "导入成功." + result;
            }else{
                resMsg += "导入失败." + result;
            }
        }catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return resMsg;
    }

    //保存tif文件数据
    public String newImportTifFile(String filePath, String province, String city, String area, String fileUuid,int dataLength, String createUser, String dateStr, int fileListCount) {
        // 返回的消息
        StringBuilder returnMsg = new StringBuilder();
        try {
            System.out.println(new Date()+"-------------------1.开始保存");
            //保存--zyt
            int count = newSaveData(filePath,province,city,area, dataLength,fileUuid,createUser,dateStr,fileListCount);
            if(count==dataLength){
                System.out.println(new Date()+"-------------------2.结束保存");
                returnMsg.append("成功导入" + count + "条数据.");
            }else{
                System.out.println(new Date()+"-------------------2.结束保存");
                returnMsg.append("导入出现异常，仅导入" + count + "条数据.");
            }
            //test--不保存数据，通过文件发布图层
//            returnMsg.append("成功导入" + dataLength + "条数据.");
            return returnMsg.toString();
        } catch (RuntimeException e) {
            log.error(e.getMessage(), e);
            return "插入或更新数据出现错误: <br/>" + e.getMessage();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return "数据导入失败, 服务器内部出现异常!";
        }
    }

    //保存tif文件数据--所有栅格值各保存1条数据
    private int newSaveData(String filePath, String province, String city, String area, int dataLength, String fileUuid, String createUser, String dateStr, int fileListCount) {
        int count = 0;
        int num = 20000;//每次保存的数据长度
        Connection conn = null;
        try {
            conn = getConnection();
            //新增
            String tempsql = "insert into sys_elevation (" +
                    "elevation_id,elevation_number," +
                    "fileuuid," +
                    "geom) values ";

            StringBuffer sql = new StringBuffer("");
            int total = dataLength;
            boolean bool = false;//是否保存
            //开始时间
            Long begin = new Date().getTime();

            System.out.println(new Date()+"-------------------1.开始readTifFile");
            //gdal读取tif文件
//            gdal.AllRegister();
            Dataset dataset = gdal.Open(filePath, gdalconstConstants.GA_ReadOnly);
            if (dataset == null) return 0;
            String projection = dataset.GetProjection();//投影
            Band band = dataset.GetRasterBand(1);//选择要读取的波段数，bandNum 从 1 开始

            int xSize = dataset.getRasterXSize();//获取宽度，数组第二维，左右方向元素长度，代表经度范围
            int ySize = dataset.getRasterYSize();//获取高度，数组第一维，上下方向元素长度，代表纬度范围

            //GeoTransform 的含义：
            //六参数信息
            double[] geoTransform = dataset.GetGeoTransform();//获取仿射矩阵，含有 6 个元素的元组
            //影像左上角投影坐标
            double[] luCoordinate = new double[2];
            luCoordinate[0] = geoTransform[0];//影像左上角横坐标：对应经度
            luCoordinate[1] = geoTransform[3];//影像左上角纵坐标：对应纬度
            //通常水平和垂直分辨率相等
            //遥感图像的垂直空间分辨率(经度间隔)
            double fblLon = geoTransform[1];
            //遥感图像的水平空间分辨率(纬度间隔)：
            double fblLat = geoTransform[5];
            //如果遥感影像方向没有发生旋转，即上北下南，则 geoTransA 与 geoTransB 为 0
            double geoTransA = geoTransform[2];
            double geoTransB = geoTransform[4];

            /*计算图像地理坐标：
            若图像中某一点的行数和列数分别为 row 和 column，则该点的地理坐标为：
            经度：xGeo = geoTransform[0] + row * geoTransform[1] + column * geoTransform[2]
            纬度：yGeo = geoTransform[3] + row * geoTransform[4] + column * geoTransform[5]
            */

            int buf[] = new int[xSize];
            String coordinate = "";
            for(int i = 0; i < ySize; i++) {
                band.ReadRaster(0, i, xSize, 1, buf);
                for(int j = 0; j < xSize; j++) {
                    //数值校验
                    if(buf[j] >= 0 && buf[j] <= 9000) {
                        //高程范围：最小值0，最大值9000，无数据值N/A
                    }else{
                        continue;
                    }
                    double luLon = geoTransform[0] + j * geoTransform[1] + i * geoTransform[2];
                    double luLat = geoTransform[3] + j * geoTransform[4] + i * geoTransform[5];

                    double ruLon = geoTransform[0] + (j + 1) * geoTransform[1] + i * geoTransform[2];
                    double ruLat = geoTransform[3] + (j + 1) * geoTransform[4] + i * geoTransform[5];

                    double rbLon = geoTransform[0] + (j + 1) * geoTransform[1] + (i + 1) * geoTransform[2];
                    double rbLat = geoTransform[3] + (j + 1) * geoTransform[4] + (i + 1) * geoTransform[5];

                    double lbLon = geoTransform[0] + j * geoTransform[1] + (i + 1) * geoTransform[2];
                    double lbLat = geoTransform[3] + j * geoTransform[4] + (i + 1) * geoTransform[5];

                    coordinate = luLon + " " + luLat + "," + ruLon + " " + ruLat + "," + rbLon + " " + rbLat + "," + lbLon + " " + lbLat;
                    coordinate += "," + luLon + " " + luLat;//与第一个点闭合
                    //获取tif文件数据值
                    int elevationNumber = buf[j];
                    //获取tif文件网格矢量数据
                    String geo = "POLYGON (("+coordinate+"))";
                    count++;
                    bool = false;//是否保存
                    if(count<total){
                        if(count % num == 0){
                            bool = true;//是否保存
                            //开始时间
                            begin = new Date().getTime();
                        }
                    }else{
                        bool = true;//是否保存
                    }
                    //空间数据
                    String geom = "ST_GeometryFromText('" + geo + "',4490)";
                    //主键
                    String elevationId = UUIDGenerator.getUUID();
                    //状态1正常0删除
                    String delFlag = "1";
                    String county = area;//区县

                    sql.append("('" + elevationId + "'," + elevationNumber
                            + ",'" + fileUuid
                            + "'," + geom +"),");

                    if(bool){
                        String sql_str = tempsql + sql.toString();
                        sql_str = sql_str.substring(0, sql_str.length() - 1);
                        PreparedStatement ps = conn.prepareStatement(sql_str);
                        //ps.executeUpdate(sql_str);
                        ps.executeUpdate();
                        if (ps != null) ps.close();
                        //结束时间
                        Long end = new Date().getTime();
                        //耗时
                        System.out.println(new Date()+"----count: " + count+",cast : " + (end - begin) / 1000 + " s");
                        //清空
                        sql.setLength(0);
                    }
                }
            }
            dataset.delete();
//            gdal.GDALDestroyDriverManager();
            System.out.println(new Date()+"-------------------2.结束readTifFile");

            //保存tif文件数据--保存数据union
            newSaveDataUnion(fileUuid,province,city,area);

        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("保存第" + count + "条数据出现异常!");
            //已保存的数量
            count = (int) Math.floor(count / num) * num;
        } finally {
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }

        return count;
    }

    //保存tif文件数据--保存数据union
    private void newSaveDataUnion(String fileUuid,String province, String city, String area) {
        Connection conn = null;
        try {
            conn = getConnection();
            //开始时间
            Long begin = new Date().getTime();
            System.out.println(new Date()+"-------------------1.开始union");
            String sql_str = "insert into sys_elevation_union (elevation_number,fileuuid,geom,province,city,county)" +
                    " select elevation_number,fileuuid,st_astext(st_union(geom)) as geom," +
                    "'"+province+"' as province,'"+city+"' as city,'"+area+"' as county from sys_elevation" +
                    " where fileuuid='"+fileUuid+"'" +
                    " GROUP BY elevation_number,fileuuid";
            PreparedStatement ps = conn.prepareStatement(sql_str);
            //ps.executeUpdate(sql_str);
            ps.executeUpdate();
            if (ps != null) ps.close();
            //结束时间
            Long end = new Date().getTime();
            //耗时
            System.out.println(new Date()+"----cast : " + (end - begin) / 1000 + " s");
            System.out.println(new Date()+"-------------------2.结束union");

            //删除数据sys_elevation
            List<String> ids = new ArrayList<String>();
            ids.add(fileUuid);
            //物理删除相关数据
            deleteData(ids);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
    }

    //更新为正在保存状态
    @Transactional(rollbackFor = Exception.class)
    public int updateSaveNowQhMapFile(QhMapFilesEntity qhMapFilesEntity) throws Exception {
        List<QhMapFilesEntity> list = new ArrayList<QhMapFilesEntity>();
        list.add(qhMapFilesEntity);
        int count = qhMapFilesImport.sqlBatchUpdateNowEntities(list);

        return count;
    }

    //批量更新为已删除状态
    @Transactional(rollbackFor = Exception.class)
    public int updateLogicDeleteQhMapFiles(List<QhMapFilesEntity> list) throws Exception {
        int count = qhMapFilesImport.sqlBatchLogicDeleteEntities(list);

        return count;
    }

    //更新为已保存状态
    @Transactional(rollbackFor = Exception.class)
    public int updateSaveQhMapFile(QhMapFilesEntity qhMapFilesEntity) throws Exception {
        List<QhMapFilesEntity> list = new ArrayList<QhMapFilesEntity>();
        list.add(qhMapFilesEntity);
        int count = qhMapFilesImport.sqlBatchUpdateEntities(list);

        return count;
    }

    //根据参数查询文件
    public List<QhMapFilesEntity> searchQhMapFilesByParams(QhMapFilesQueryParams queryParams) {
        List<QhMapFilesEntity> list = qhMapFilesNativeRepository.searchMapFilesByJDBC(queryParams);

        return list;
    }

    //保存到上传文件管理表
    private void saveMapFiles(QhMapFilesEntity qhMapFilesEntity) throws Exception {
        List<QhMapFilesEntity> list = new ArrayList<QhMapFilesEntity>();
        list.add(qhMapFilesEntity);
        String affiliatedFileName = qhMapFilesEntity.getAffiliatedFileName();
        String province = qhMapFilesEntity.getProvince();
        String city = qhMapFilesEntity.getCity();
        String area = qhMapFilesEntity.getArea();
        //逻辑删除未保存的文件
        deleteMapFileByParams(affiliatedFileName, province, city, area);
        //保存
        qhMapFilesImport.sqlBatchSaveEntities(list);
    }

    //逻辑删除未保存的文件
    private void deleteMapFileByParams(String affiliatedFileName, String province, String city, String area) {
        //查询上传文件表
        QhMapFilesQueryParams qhMapFilesQueryParams = new QhMapFilesQueryParams();
        qhMapFilesQueryParams.setProvince(province);
        qhMapFilesQueryParams.setCity(city);
        qhMapFilesQueryParams.setArea(area);
        //qhMapFilesQueryParams.setAffiliatedFileName(affiliatedFileName);
        qhMapFilesQueryParams.setType("地形地貌（高程）_");//上传类型（地形地貌（高程）_）
        //查询文件（未删除）
        List<QhMapFilesEntity> list = qhMapFilesImport.searchMapFilesUnSaved(qhMapFilesQueryParams);
        if(!PlatformObjectUtils.isEmpty(list) && list.size() > 0) {
            //逻辑删--上传文件表
            qhMapFilesImport.sqlBatchLogicDeleteEntities(list);
        }
    }

    //校验Tif文件是否为2000坐标系
    public boolean checkCGCS2000Tif(String path) {
        String name = "";
//        gdal.AllRegister();
        Dataset dataset = gdal.Open(path, gdalconstConstants.GA_ReadOnly);
        if (dataset == null) return false;
        name = dataset.GetProjection();//获取地理信息
        dataset.delete();
//        gdal.GDALDestroyDriverManager();
        if (name.contains("China Geodetic Coordinate System 2000") || name.contains("GCS_China_Geodetic_Coordinate_System_2000")) return true;

        return false;
    }

    //获取tif文件全部数据长度--zyt
    public int getDataLengthByTIF(String tifFileName) {
//        gdal.AllRegister();

        Dataset dataset = gdal.Open(tifFileName, gdalconstConstants.GA_ReadOnly);
        if (dataset == null) return -1;

        Band band = dataset.GetRasterBand(1);

        int xSize = dataset.getRasterXSize();
        int ySize = dataset.getRasterYSize();

        //GeoTransform 的含义：
        //六参数信息
        double[] geoTransform = dataset.GetGeoTransform();//获取仿射矩阵，含有 6 个元素的元组
        //影像左上角投影坐标
        double[] luCoordinate = new double[2];
        double lon = geoTransform[0];//影像左上角横坐标：对应经度
        double lat = geoTransform[3];//影像左上角纵坐标：对应纬度
        //判断经纬度值是否正常
        if(lon<0 || lon>180 || lat<0 || lat>90){
            return 0;
        }

        int count = 0;
        int buf[] = new int[xSize];
        for(int i = 0; i < ySize; i++) {
            band.ReadRaster(0, i, xSize, 1, buf);
            for(int j = 0; j < xSize; j++) {
                //高程范围：最小值0，最大值9000，无数据值N/A
                if(buf[j] >= 0 && buf[j] <= 9000) {
                    count++;
                }
            }
        }
        dataset.delete();
//        gdal.GDALDestroyDriverManager();

        return count;
    }

    //获取tif文件全部数据值列表
    public List<Object> getAllValueListByTIF(String tifFileName) {
        List<Object> result = new ArrayList<Object>();
        List<Integer> valueList = new ArrayList<Integer>();//栅格数值列表
        List<Integer> countList = new ArrayList<Integer>();//计数列表
//        gdal.AllRegister();

        Dataset dataset = gdal.Open(tifFileName, gdalconstConstants.GA_ReadOnly);
        if (dataset == null) return null;

        Band band = dataset.GetRasterBand(1);

        int xSize = dataset.getRasterXSize();
        int ySize = dataset.getRasterYSize();

        int buf[] = new int[xSize];
        for(int i = 0; i < ySize; i++) {
            band.ReadRaster(0, i, xSize, 1, buf);
            for(int j = 0; j < xSize; j++) {
                //数值校验
                if(buf[j] >= 0 && buf[j] <= 9000) {
                    //高程范围：最小值0，最大值9000，无数据值N/A
                }else{
                    continue;
                }
                int index = valueList.indexOf(buf[j]);
                if(index==-1){
                    valueList.add(buf[j]);
                    countList.add(1);
                }else{
                    int count = countList.get(index);
                    countList.set(index,count+1);
                }
            }
        }
        dataset.delete();
//        gdal.GDALDestroyDriverManager();

        result.add(valueList);
        result.add(countList);

        return result;
    }

    //获取tif文件数据值
    public String getValueByTIF(String tifFileName) {
//        gdal.AllRegister();

        Dataset dataset = gdal.Open(tifFileName, gdalconstConstants.GA_ReadOnly);
        if (dataset == null) return null;

        Band band = dataset.GetRasterBand(1);

        int xSize = dataset.getRasterXSize();
        int ySize = dataset.getRasterYSize();

        StringBuilder sb = new StringBuilder();
        int buf[] = new int[xSize];
        for(int i = 0; i < ySize; i++) {
            band.ReadRaster(0, i, xSize, 1, buf);
            for(int j = 0; j < xSize; j++) {
                //数值校验
                if(buf[j] >= 0 && buf[j] <= 9000) {
                    //高程范围：最小值0，最大值9000，无数据值N/A
                }else{
                    continue;
                }
                sb.append(buf[j] + "|");
            }
        }
        String gridDataStr = sb.toString();
        gridDataStr = gridDataStr.substring(0, gridDataStr.length() - 1);
        dataset.delete();
//        gdal.GDALDestroyDriverManager();

        return gridDataStr;
    }

    //获取tif文件网格矢量数据
    public String getRectsByTIF(String tifFileName) {
//        gdal.AllRegister();

        Dataset dataset = gdal.Open(tifFileName, gdalconstConstants.GA_ReadOnly);
        if (dataset == null) return null;
        String projection = dataset.GetProjection();//投影
        Band band = dataset.GetRasterBand(1);//选择要读取的波段数，bandNum 从 1 开始

        int xSize = dataset.getRasterXSize();//获取宽度，数组第二维，左右方向元素长度，代表经度范围
        int ySize = dataset.getRasterYSize();//获取高度，数组第一维，上下方向元素长度，代表纬度范围

        //GeoTransform 的含义：
        //六参数信息
        double[] geoTransform = dataset.GetGeoTransform();//获取仿射矩阵，含有 6 个元素的元组
        //影像左上角投影坐标
        double[] luCoordinate = new double[2];
        luCoordinate[0] = geoTransform[0];//影像左上角横坐标：对应经度
        luCoordinate[1] = geoTransform[3];//影像左上角纵坐标：对应纬度
        //通常水平和垂直分辨率相等
        //遥感图像的垂直空间分辨率(经度间隔)
        double fblLon = geoTransform[1];
        //遥感图像的水平空间分辨率(纬度间隔)：
        double fblLat = geoTransform[5];
        //如果遥感影像方向没有发生旋转，即上北下南，则 geoTransA 与 geoTransB 为 0
        double geoTransA = geoTransform[2];
        double geoTransB = geoTransform[4];

        /*计算图像地理坐标：
        若图像中某一点的行数和列数分别为 row 和 column，则该点的地理坐标为：
        经度：xGeo = geoTransform[0] + row * geoTransform[1] + column * geoTransform[2]
        纬度：yGeo = geoTransform[3] + row * geoTransform[4] + column * geoTransform[5]
        */

        int count = 0;
        int buf[] = new int[xSize];
        String coordinate = "";
        StringBuilder sb = new StringBuilder();
        sb.append("MULTIPOLYGON (");
        for(int i = 0; i < ySize; i++) {
            band.ReadRaster(0, i, xSize, 1, buf);
            for(int j = 0; j < xSize; j++) {
                //数值校验
                if(buf[j] >= 0 && buf[j] <= 9000) {
                    //高程范围：最小值0，最大值9000，无数据值N/A
                }else{
                    continue;
                }
                double luLon = geoTransform[0] + j * geoTransform[1] + i * geoTransform[2];
                double luLat = geoTransform[3] + j * geoTransform[4] + i * geoTransform[5];

                double ruLon = geoTransform[0] + (j + 1) * geoTransform[1] + i * geoTransform[2];
                double ruLat = geoTransform[3] + (j + 1) * geoTransform[4] + i * geoTransform[5];

                double rbLon = geoTransform[0] + (j + 1) * geoTransform[1] + (i + 1) * geoTransform[2];
                double rbLat = geoTransform[3] + (j + 1) * geoTransform[4] + (i + 1) * geoTransform[5];

                double lbLon = geoTransform[0] + j * geoTransform[1] + (i + 1) * geoTransform[2];
                double lbLat = geoTransform[3] + j * geoTransform[4] + (i + 1) * geoTransform[5];

                //coordinate = luLon + " " + luLat + "," + ruLon + " " + ruLat + "," + rbLon + " " + rbLat + "," + lbLon + " " + lbLat + "|";
                if(count>0){
                    coordinate = ", ";
                }else{
                    coordinate = "";
                }
                coordinate += "((" + luLon + " " + luLat + ", " + ruLon + " " + ruLat + ", " + rbLon + " " + rbLat + ", " + lbLon + " " + lbLat + ", " + luLon + " " + luLat + "))";
                sb.append(coordinate);
                count++;
                if(count%5000==0){
                    System.out.println("----count: " + count);
                }
            }
        }
        System.out.println("----count: " + count);
        sb.append(")");
        coordinate = sb.toString();
        //coordinate = coordinate.substring(0, coordinate.length() - 1);
        dataset.delete();
//        gdal.GDALDestroyDriverManager();
        return coordinate;
    }

    //读取cpg文件编码
    public String readCPG(String path) {
        String codeType = "UTF-8";
        StringBuffer result = new StringBuffer();
        File file = new File(path);
        if (!file.exists()) return "";
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(file));
            String tempString = null;
            while ((tempString = reader.readLine()) != null) {
                result.append(tempString);
            }
            reader.close();
            //返回结果
            codeType = result.toString();
            codeType = codeType.toUpperCase();//转换大写
        } catch (IOException e) {
            e.printStackTrace();
        }
        return codeType;
    }

    public String readPRJ(String path) {
        StringBuffer result = new StringBuffer();
        File file = new File(path);
        if (!file.exists()) return "";
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(file));
            String tempString = null;
            while ((tempString = reader.readLine()) != null) {
                result.append(tempString);
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result.toString();
    }

    public SimpleFeatureCollection readShp(String path, Filter filter, String codeType) {
        SimpleFeatureSource featureSource = readStoreByShp(path, codeType);
        if (featureSource == null) return null;
        try {
            return filter != null ? featureSource.getFeatures(filter) : featureSource.getFeatures();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public SimpleFeatureSource readStoreByShp(String path, String codeType) {
        File file = new File(path);
        FileDataStore store;
        SimpleFeatureSource featureSource = null;
        try {
            store = FileDataStoreFinder.getDataStore(file);
            ((ShapefileDataStore) store).setCharset(Charset.forName(codeType));
            featureSource = store.getFeatureSource();
            store.dispose();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return featureSource;
    }

    //获取省市县所在区域边界列表
    public List<com.css.fxfzypg.modules.spatialData.repository.entity.Point[]> getDistrictBoundaryByString(String coordinate){
        List<com.css.fxfzypg.modules.spatialData.repository.entity.Point[]> boundaries = new ArrayList<>();
        if (coordinate == null || "".equals(coordinate)) {
            System.out.println("NoDistrictBoundaryData");
        } else {
            coordinate = coordinate.substring(coordinate.indexOf("(((") + 3, coordinate.lastIndexOf(")))"));
            coordinate = coordinate.replace(")), ((", "|");
            //coordinate = coordinate.replace("), (", "#");
            coordinate = coordinate.replace("), (", "|");
            String[] coordinates = StringUtils.split(coordinate, "|");
            for (int j = 0; j < coordinates.length; j++) {
                coordinates[j] = coordinates[j].replace(", ",";");
                coordinates[j] = coordinates[j].replace(" ",",");
                String[] lonlats = StringUtils.split(coordinates[j],";");
                com.css.fxfzypg.modules.spatialData.repository.entity.Point[] points = new com.css.fxfzypg.modules.spatialData.repository.entity.Point[lonlats.length];
                for (int i = 0;i < lonlats.length;i++) {
                    String[] lonlat = StringUtils.split(lonlats[i], ",");
                    com.css.fxfzypg.modules.spatialData.repository.entity.Point point = new com.css.fxfzypg.modules.spatialData.repository.entity.Point();
                    point.x = Double.parseDouble(lonlat[0]);
                    point.y = Double.parseDouble(lonlat[1]);
                    points[i] = point;
                }
                boundaries.add(points);
            }
        }

        return boundaries;
    }

    public String reverseWktMultiPolygon(String wktPolygon) {
        String oldWkt = wktPolygon;
        oldWkt = oldWkt.substring(oldWkt.indexOf("(((") + 3, oldWkt.lastIndexOf(")))"));
        oldWkt = oldWkt.replace(")), ((", "|");
        oldWkt = oldWkt.replace("), (", "#");

        String wktPolygon1 = "";
        String[] polygon1 = StringUtils.split (oldWkt, "|");
        for (int i = 0; i < polygon1.length; i++) {
            if(polygon1[i].indexOf("#")!=-1){
                String[] polygon2 = StringUtils.split(polygon1[i], "#");
                for (int j = 0; j < polygon2.length; j++) {
                    String wktPolygon2 = "";
                    String[] coords = polygon2[j].split(", ");
                    for (int k = 0; k < coords.length; k++) {
                        String[] lonLat = coords[k].split(" ");
                        String lon = lonLat[1];
                        String lat = lonLat[0];
                        wktPolygon2 += lon + " " + lat + ", ";
                    }
                    wktPolygon1 += wktPolygon2.substring(0, wktPolygon2.length() - 2) + "), (";
                }
                wktPolygon1 = wktPolygon1.substring(0, wktPolygon1.length() - 4) + ")), ((";
            }else{
                String wktPolygon2 = "";
                String[] coords = polygon1[i].split(", ");
                for (int k = 0; k < coords.length; k++) {
                    String[] lonLat = coords[k].split(" ");
                    String lon = lonLat[1];
                    String lat = lonLat[0];
                    wktPolygon2 += lon + " " + lat + ", ";
                }
                wktPolygon1 += wktPolygon2.substring(0, wktPolygon2.length() - 2) + ")), ((";
            }
        }
        wktPolygon1 = wktPolygon1.substring(0, wktPolygon1.length() - 6);

        return "MULTIPOLYGON (((" + wktPolygon1 + ")))";
    }

    public String reverseWktPolygon(String wktPolygon) {
        String oldWkt = wktPolygon;
        oldWkt = oldWkt.substring(oldWkt.indexOf("(") + 2, oldWkt.lastIndexOf("))"));

        String polygonWkt = "Polygon (", coordinate = "";
        String sp = oldWkt.indexOf("),(") != -1 ? "),(" : (oldWkt.indexOf("), (") != -1 ? "), (" : "");
        if ("".equals(sp)) {
            coordinate = "(";
            String[] coordinates = oldWkt.split(",");
            for (int i = 0; i < coordinates.length; i++) {
                String[] coords = coordinates[i].split(" ");
                coordinate += coords[1] + " " + coords[0] + ",";
            }
            coordinate = coordinate.substring(0, coordinate.length() - 1) + ")";
            polygonWkt += coordinate + ")";
        } else {
            oldWkt = oldWkt.replace(sp, "#"); sp = "#";
            String[] coordinates = oldWkt.split(sp);
            for (int i = 0; i < coordinates.length; i++) {
                coordinate = coordinates[i];
                String _coordinates = "(";
                String[] coords = coordinate.split(","), _coords = null;
                for (int j = 0; j < coords.length; j++) {
                    _coords = coords[j].split(" ");
                    _coordinates += _coords[1] + " " + _coords[0] + ",";
                }
                _coordinates = _coordinates.substring(0, _coordinates.length() - 1) + ")";
                polygonWkt += _coordinates + ",";
            }
            polygonWkt += polygonWkt.substring(0, polygonWkt.length() - 1) + ")";
        }
        return polygonWkt;
    }

    public String reverseWktPoint(String wktPoint) {
        String oldWkt = wktPoint;
        oldWkt = oldWkt.substring(oldWkt.indexOf("(") + 1, oldWkt.lastIndexOf(")"));
        String[] coords = oldWkt.split(" ");
        return "POINT (" + coords[1] + " " + coords[0] + ")";
    }

    public String reverseWktMultiPoint(String wktMultiPoint) {
        String oldWkt = wktMultiPoint;
        oldWkt = oldWkt.substring(oldWkt.indexOf("(") + 2, oldWkt.lastIndexOf(")") - 1);
        String sp = oldWkt.indexOf("),(") != -1 ? "),(" : (oldWkt.indexOf("), (") != -1 ? "), (" : "");
        String[] coordinates = StringUtils.split(oldWkt, sp);
        String newWkt = "MULTIPOINT ((", coordinate = "";
        String[] coords = null;
        for (int i = 0; i < coordinates.length; i++) {
            coordinate = coordinates[i];
            coords = coordinate.split(" ");
            //newWkt += "(" + coords[1] + " " + coords[0] + "),";
            newWkt += coords[1] + " " + coords[0] + ",";
        }
        newWkt = newWkt.substring(0, newWkt.length() - 1) + "))";
        return newWkt;
    }

    public boolean newGeometryIsEqualsCoordinate(String wkt, String lon, String lat) {
        String wktPart = "";
        if (wkt.toLowerCase().indexOf("multipoint") != -1) {
            wktPart = wkt.substring(wkt.indexOf("(") + 2, wkt.lastIndexOf(")") - 1);
        } else if (wkt.toLowerCase().indexOf("point") != -1) {
            wktPart = wkt.substring(wkt.indexOf("(") + 1, wkt.lastIndexOf(")"));
        }

        int det = 1 + 8;//保留8位小数判断
        String[] array = wktPart.split(" ");
        String longitude = array[0], latitude = array[1];
        String newWktLongitudeStr = newKeepDecimalDigits(longitude, det), newWktLatitudeStr = newKeepDecimalDigits(latitude, det);
        String newLongitudeStr = newKeepDecimalDigits(lon, det), newLatitudeStr = newKeepDecimalDigits(lat, det);

        double newWktLongitude = Double.parseDouble(newWktLongitudeStr), newWktLatitude = Double.parseDouble(newWktLatitudeStr);
        double newLongitude = Double.parseDouble(newLongitudeStr), newLatitude = Double.parseDouble(newLatitudeStr);

        //if (newWktLongitude == newLongitude && newWktLatitude == newLatitude) return true;
        //判断是否在10-6次方内
        double tempLon = Math.abs(newWktLongitude - newLongitude);
        double tempLat = Math.abs(newWktLatitude - newLatitude);
        if(tempLon<0.000001 && tempLat<0.000001){
            return true;
        }

        //判断保留8位（不四舍五入）属性字段经纬度与geometry是否一致
        if(getGeometryIsEqualsCoordinateBool(longitude, latitude, lon, lat, det)) return true;

        return false;
    }

    private String newKeepDecimalDigits(String floatStr, int det) {
        int index = floatStr.indexOf("."), len = floatStr.length();
        if (index == -1) return floatStr;
        int temp=det+1;
        String tempfloatPart=floatStr.substring(index + 1, (len > (index + temp)) ? (index + temp) : len);
        String floatPart = floatStr.substring(index + 1, (len > (index + det)) ? (index + det) : len);

        boolean bool = false;//判断是否四舍五入
        int findex=0;
        String sindex="";
        if(tempfloatPart.length()>floatPart.length()){
            if(tempfloatPart.startsWith(floatPart)&&(tempfloatPart.endsWith("9") || tempfloatPart.endsWith("8") || tempfloatPart.endsWith("7") || tempfloatPart.endsWith("6") || tempfloatPart.endsWith("5"))){
                for(int i=floatPart.length()-1;i>=0;i--){
                    String subStr = floatPart.substring(i, i+1);
                    if(subStr.equals("9")){
                        continue;
                    }
                    findex=i;
                    sindex=Integer.toString(Integer.parseInt(subStr)+1);
                    break;
                }
                floatPart= floatPart.substring(0, findex)+ sindex;
                bool = true;
            }
        }

        String newFloatStr = floatStr.substring(0, index) + "." + floatPart;
        if(bool && sindex.equals("")){//floatPart都是9
            newFloatStr = Integer.toString(Integer.parseInt(floatStr.substring(0, index))+1);
        }

        return newFloatStr;
    }

    //保留8位（不四舍五入）
    private String newKeepDecimalDigits2(String floatStr, int det) {
        int index = floatStr.indexOf("."), len = floatStr.length();
        if (index == -1) return floatStr;
        String floatPart = floatStr.substring(index + 1, (len > (index + det)) ? (index + det) : len);
        String newFloatStr = floatStr.substring(0, index) + "." + floatPart;

        return newFloatStr;
    }

    //判断保留8位（不四舍五入）属性字段经纬度与geometry是否一致
    private boolean getGeometryIsEqualsCoordinateBool(String longitude, String latitude, String lon, String lat, int det){
        boolean bool = false;
        String newWktLongitudeStr = newKeepDecimalDigits2(longitude, det), newWktLatitudeStr = newKeepDecimalDigits2(latitude, det);
        String newLongitudeStr = newKeepDecimalDigits2(lon, det), newLatitudeStr = newKeepDecimalDigits2(lat, det);

        double newWktLongitude = Double.parseDouble(newWktLongitudeStr), newWktLatitude = Double.parseDouble(newWktLatitudeStr);
        double newLongitude = Double.parseDouble(newLongitudeStr), newLatitude = Double.parseDouble(newLatitudeStr);

        //if (newWktLongitude == newLongitude && newWktLatitude == newLatitude) bool= true;
        //判断是否在10-6次方内
        double tempLon = Math.abs(newWktLongitude - newLongitude);
        double tempLat = Math.abs(newWktLatitude - newLatitude);
        if(tempLon<0.000001 && tempLat<0.000001){
            bool= true;
        }

        return bool;
    }

    //截取8位小数（不四舍五入）
    public String getNewDecimalDigits(String floatStr) {
        int det = 1 + 8;
        int index = floatStr.indexOf("."), len = floatStr.length();
        if (index == -1) return floatStr;
        String floatPart = floatStr.substring(index + 1, (len > (index + det)) ? (index + det) : len);
        String newFloatStr = floatStr.substring(0, index) + "." + floatPart;

        return newFloatStr;
    }

    //地球半径,单位 km
    private double EARTH_RADIUS = 6378.137;

    //根据经纬度，计算两点间的距离
    public double getDistance(double longitude1, double latitude1, double longitude2, double latitude2) {
        // 纬度
        double lat1 = Math.toRadians(latitude1);
        double lat2 = Math.toRadians(latitude2);
        // 经度
        double lng1 = Math.toRadians(longitude1);
        double lng2 = Math.toRadians(longitude2);
        // 纬度之差
        double a = lat1 - lat2;
        // 经度之差
        double b = lng1 - lng2;
        // 计算两点距离的公式
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
                Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2)));
        // 弧长乘地球半径, 返回单位: 千米
        s =  s * EARTH_RADIUS;
        return s;
    }

    //判断6秒距离200
    public boolean isLessSixSecondDistance(List<Double> allLonList,List<Double> allLatList) {
        for(int i=0;i<allLonList.size();i++){
            if(i>100){//只判断100个点
                break;
            }
            double lng1 = allLonList.get(i);
            double lat1 = allLatList.get(i);
            boolean bool = false;
            double minDistance = -1;//最小距离
            for(int j=0;j<allLonList.size();j++){
                if(j==i){
                    continue;
                }
                double lng2 = allLonList.get(j);
                double lat2 = allLatList.get(j);
                double distance = getDistance(lng1,lat1,lng2,lat2);
                if(minDistance==-1 || distance<minDistance){
                    minDistance = distance;
                }
                if(distance<0.25){//250米
                    bool = true;
                    break;
                }
            }
            if(bool==false){
                System.out.println("第"+i+"条数据判断6秒距离不在250米内："+minDistance+"km--minDistance");
                System.out.println("第"+i+"条数据经纬度："+lng1+","+lat1);
                return false;
            }
        }

        return true;
    }

    private double GLOBAL_THRESH = 1E-6;

    //校验点数据是否在省市县所在区域边界内
    public boolean newCheckPointIsInDistrictBoundary(List<com.css.fxfzypg.modules.spatialData.repository.entity.Point[]> boundaries,String lonStr, String latStr) {
        com.css.fxfzypg.modules.spatialData.repository.entity.Point point = new com.css.fxfzypg.modules.spatialData.repository.entity.Point(Double.parseDouble(lonStr), Double.parseDouble(latStr));
        com.css.fxfzypg.modules.spatialData.repository.entity.Point[] boundary = null;
        boolean bool = false;
        if(boundaries!=null && boundaries.size()>0){
            for (int k = 0; k < boundaries.size(); k++) {
                boundary = boundaries.get(k);
                if (AreaBoundaryUtil.isPointInPolygon(point, boundary)){
                    bool = true;
                    break;
                } else {//判断容差距离
                    double minDis = Double.MAX_VALUE;
                    for (int n = 0; n < boundary.length - 1; n++) {
                        com.css.fxfzypg.modules.spatialData.repository.entity.Point p1 = boundary[n], p2 = boundary[n + 1];
                        double d = AreaBoundaryUtil.pointToLine(p1.x, p1.y, p2.x, p2.y, point.x, point.y);
                        if (minDis > d) minDis = d;
                    }
                    if (minDis < GLOBAL_THRESH) {
                        bool = true;
                        break;
                    }
                }
            }
            if (bool == false){
                String temp = "点："+point+"--------不在行政区划范围内----";
                System.out.println(temp);
                return false;
            }
        }else{
            System.out.println("无行政区划范围----");
            return false;
        }

        return true;
    }

    private String strWKTMercator = "PROJCS[\"CGCS2000_GK_Zone_20\",GEOGCS[\"GCS_China_Geodetic_Coordinate_System_2000\",DATUM[\"D_China_2000\",SPHEROID[\"CGCS2000\",6378137.0,298.257222101]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Gauss_Kruger\"],PARAMETER[\"False_Easting\",20500000.0],PARAMETER[\"False_Northing\",0.0],PARAMETER[\"Central_Meridian\",117.0],PARAMETER[\"Scale_Factor\",1.0],PARAMETER[\"Latitude_Of_Origin\",0.0],UNIT[\"Meter\",1.0]]";

    public void setStrWKTMercator(String wKTMercator){
        strWKTMercator = wKTMercator;
    }

    public String wkt2lonLat(String wktPolygon){
        Geometry geomtry = null;
        try {
            GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
            WKTReader reader = new WKTReader(geometryFactory);
            geomtry = reader.read(wktPolygon);
            geomtry = webMercator2lonLat(geomtry);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        if (geomtry != null)
            return geomtry.toString();
        else return null;
    }

    public Geometry webMercator2lonLat(Geometry geom){
        try{
            CoordinateReferenceSystem sourceTarget = CRS.parseWKT(strWKTMercator);
            CoordinateReferenceSystem crsTarget = CRS.decode("EPSG:4490");
            MathTransform transform = CRS.findMathTransform(sourceTarget, crsTarget, true);
            //MathTransform transform = CRS.findMathTransform(sourceTarget, DefaultGeographicCRS.WGS84, true);
            return JTS.transform(geom, transform);
        }
        catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    //获取重点活动ID（11位）
    public String getZdhdId(String dateStr, int fileListCount){
        String zdhdId = dateStr;
        fileListCount = fileListCount - 1;//从0开始
        if(fileListCount<10){
            zdhdId += "00" + fileListCount;
        }else if(fileListCount<100){
            zdhdId += "0" + fileListCount;
        }else if(fileListCount<1000){
            zdhdId += String.valueOf(fileListCount);
        }

        return zdhdId;
    }

    //获取流水码（5位)
    public String getTempCountNum(int count){
        count = count - 1;//从0开始
        //流水码（5位）
        String tempCountNum = "00000";
        if(count<10){
            tempCountNum = "0000" + count;
        }else if(count<100){
            tempCountNum = "000" + count;
        }else if(count<1000){
            tempCountNum = "00" + count;
        }else if(count<10000){
            tempCountNum = "0" + count;
        }else if(count<100000){
            tempCountNum = String.valueOf(count);
        }else{//超过5位
            tempCountNum = String.valueOf(count);
        }

        return tempCountNum;
    }

    //判断字符串是否为整数或者小数（大于0）
    public boolean isNumericFloat(String str){
        Pattern pattern = Pattern.compile("[0-9]*\\.?[0-9]+");
        Matcher isNum = pattern.matcher(str);
        if (!isNum.matches()) {
            return false;
        }
        float temp = Float.parseFloat(str);
        if(temp>0){
            return true;
        }else{
            return false;
        }
    }
}
